package com.mzsoft.ai;

import com.alibaba.fastjson.JSON;
import com.mzsoft.ai.service.OperateDataService;
import com.mzsoft.ai.utils.ReadPlanData;
import com.mzsoft.ai.utils.file.FileUtil;
import com.mzsoft.ai.utils.file.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

/**
 * 导入模板处理
 * @author libq
 */
public class DataImportApplication {

    private static Logger logger = LoggerFactory.getLogger(DataImportApplication.class);

    public static void main(String[] args) throws SQLException, IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {

        String userDir = System.getProperty("user.dir");
        String configPath = userDir+"/config/servers.json";
        logger.info("userDir:"+userDir);
        if(!new File(configPath).exists()){
            throw new RuntimeException("配置服务器文件【"+configPath+"】不存在!");
        }

        String appServerMapStr = FileUtil.getFileContent(configPath);
        logger.debug("appServerMapStr:"+appServerMapStr);
        Map<String,Object> appServerMap = JSON.parseObject(appServerMapStr, Map.class);
        logger.debug("jdbc链接信息:"+JSON.toJSONString(appServerMap));

        for(String businessCode : appServerMap.keySet()){
            operateBusinessExcelData(businessCode,appServerMap);
        }
    }

    /**
     * 业务操作不同文件夹下的excel数据
     * @param businessCode
     * @param appServerMap
     */
    private static void operateBusinessExcelData(String businessCode, Map<String, Object> appServerMap) throws SQLException, IOException {

        logger.debug("operate business excel data start ......");
        String basePath = System.getProperty("user.dir");

        Map<String,Object> appServer = (Map<String, Object>) appServerMap.get(businessCode);
        String folderPath = (String) appServer.get("folderPath");
        Map<String,String> fieldMap = (Map<String, String>) appServer.get("fieldMap");
        Map<String,Object> multiSheetFieldMap = (Map<String, Object>) appServer.get("multiSheetFieldMap");


        logger.debug("folderPath:"+folderPath);
        List<String> fileList = FileUtils.getAllFileName(basePath+folderPath, false, "file");
        logger.debug("fileList:"+JSON.toJSONString(fileList));
        for(String filePath : fileList){
            //读取excel数据
            if(multiSheetFieldMap != null && !multiSheetFieldMap.isEmpty()){
                Map<String, Object> resultMap = ReadPlanData.readMultiSheetData(filePath, multiSheetFieldMap);
                logger.debug("excel读取转换后数据："+resultMap);

                //将excel中附件写入临时表
                operateMultiBusinessData(businessCode,appServer,resultMap);

            }else {
                List<Map<String, Object>> result = ReadPlanData.readExcelData(filePath, fieldMap);
                logger.debug("excel读取转换后数据："+result);
                operateBusiness(businessCode,appServer,result);
            }
        }

        logger.debug("operate business excel data end ......");
    }

    private static void operateMultiBusinessData(String businessCode, Map<String, Object> appServer, Map<String, Object> resultMap) throws SQLException, IOException {
        logger.debug("operate business data start ......");

        String folderPath = (String) appServer.get("folderPath");
        Map<String,Object> multiSheetFieldMap = (Map<String, Object>) appServer.get("multiSheetFieldMap");

        List<String> sqlList = (List<String>) appServer.get("sqlList");

        //将excel中附件写入临时表
        OperateDataService.operateMultiData(businessCode,multiSheetFieldMap,resultMap);

        //将临时表数据写入到目标表
        OperateDataService.insertData(folderPath,sqlList);

        logger.debug("operate business data start ......");
    }

    private static void operateBusiness(String businessCode,Map<String, Object> appServer, List<Map<String, Object>> result) throws SQLException, IOException {

        logger.debug("operate business data start ......");

        String folderPath = (String) appServer.get("folderPath");
        Map<String,String> fieldMap = (Map<String, String>) appServer.get("fieldMap");
        List<String> sqlList = (List<String>) appServer.get("sqlList");

        //将excel中附件写入临时表
        OperateDataService.queryData(businessCode,fieldMap,result);

        //将临时表数据写入到目标表
        OperateDataService.insertData(folderPath,sqlList);

        logger.debug("operate business data start ......");
    }

    /**
     * 根据不同业务，具体操作业务数据
     * @param businessCode
     * @param fieldMap
     * @param result
     * @param sqlList
     * @throws SQLException
     */
    private static void operateBusiness2(String businessCode, Map<String, String> fieldMap, List<Map<String, Object>> result, List<String> sqlList) throws SQLException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {

        logger.debug("operate business data start ......");
        // 1、获取类
        Class clazz = Class.forName("com.mzsoft.ai.service."+businessCode);

        // 2、通过调用无参构造方法  创建对象
        // newInstance()只能调用无参，不然会报实例化异常 InstantiationException
        Object obj = clazz.newInstance();

        // 3、获取方法  因为方法有可能重载，所以要指定参数类型和个数，位置
        Method queryDataMethod = clazz.getMethod("queryData",String.class,Map.class, List.class);

        // 如果获取的方法是私有，则需要取消检查。不然会报非法访问异常 IllegalAccessException
        //   method.setAccessible(true);
        // 4、调用方法
        result = (List<Map<String, Object>>) queryDataMethod.invoke(obj,businessCode,fieldMap,result);
        logger.debug("汇总后数据集："+result);

        Method InsertDataMethod = clazz.getMethod("insertData",List.class);
        InsertDataMethod.invoke(obj,sqlList);
        logger.debug("operate business data start ......");
    }
}
